package com.yuhang.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuhang.demo.common.MD5;
import com.yuhang.demo.common.Result;

import com.yuhang.demo.entity.*;
import com.yuhang.demo.exceptionHandler.MyException;
import com.yuhang.demo.service.RoleService;
import com.yuhang.demo.service.UserExtendService;
import com.yuhang.demo.service.UserRoleXrefService;
import com.yuhang.demo.service.impl.UserServiceImpl;
import com.yuhang.demo.util.ExceptionUtil;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import com.yuhang.demo.service.UserService;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.*;


/**
 * 用户表
 *
 * @author yyh
 * @email yyh@demo.com
 * @date 2021-07-15 16:24:33
 */
@RestController
@RequestMapping("demo/user")
@RefreshScope
public class UserController {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private UserExtendService userExtendService;

    @Autowired
    private UserRoleXrefService userRoleXrefService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @GetMapping("/list")
    public Result getList() {

        List<UserEntity> list = userService.list(null);
        return Result.ok().data("list", list);

    }

    /**
     * 新增用户 可以添加角色，扩展信息
     * 角色不填 默认角色 ，扩展不填 无
     */
    @ApiOperation(value = "添加用户")
    @PostMapping("/create")
    public Result createUser(@RequestBody TotalEntity totalEntity) {

        Boolean flag = userService.create(totalEntity);

        if (flag) {
            return Result.ok().message("用户创建成功");
        }
        return Result.error().message("system error");
    }

    /**
     * 登录功能
     */
    @ApiOperation(value = "登录功能")
    @PostMapping("/login")
    public Result login(@RequestBody UserEntity userEntity) {

        String phone = userEntity.getPhone();
        String password = userEntity.getPassword();

        //获取redis中的缓存数据
        String cache = redisTemplate.opsForValue().get(phone);
        if (!StringUtils.isEmpty(cache)) {
            return Result.ok().message("登录成功");
        }


        UserEntity entity = this.userService.login(userEntity);

        //加入缓存
        redisTemplate.opsForValue().set(phone, password);

        //查询扩展信息用于返回
        QueryWrapper<UserExtendEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", entity.getId());
        UserExtendEntity extend = this.userExtendService.getOne(queryWrapper);

        //返回当前用户的角色
        QueryWrapper<UserRoleXrefEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", entity.getId());
        List<UserRoleXrefEntity> list = userRoleXrefService.list(wrapper);

        //遍历角色列表
        List<String> roleList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Integer roleId = list.get(i).getRoleId();
            RoleEntity byId = roleService.getById(roleId);
            roleList.add(byId.getRoleName());
        }

        //开启一个线程将输出结果输出到文件中
        threadPoolExecutor.execute(() -> {
            FileOutputStream fo = null;

            try {
                fo = new FileOutputStream("C:\\Users\\Administrator\\IdeaProjects\\demo\\1.txt", true);

                byte[] bytes = entity.toString().getBytes();
                fo.write(bytes);

                byte[] bytes1 = extend.toString().getBytes();
                fo.write(bytes1);

                //推荐使用，具有良好的跨平台性
                String newLine = System.getProperty("line.separator");
                fo.write(newLine.getBytes());

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    fo.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    fo.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                threadPoolExecutor.shutdown();
            }

        });

        return Result.ok().data("extend", extend).data("user", entity).data("roles", roleList.toString());
    }

    /**
     * 获取当前用户信息
     */
    @ApiOperation(value = "获取当前用户信息")
    @PostMapping("/getCurrentUser")
    public Result getCurrentUser(@RequestBody JSONObject jsonObject) {

        String phone = jsonObject.getString("phone");

        //获取redis中的缓存
        String cache = redisTemplate.opsForValue().get(phone);
        return Result.ok().message("登录成功").data("username", phone).data("password", cache);
    }


    /**
     * 修改用户  修改用户的同时可以修改扩展信息，但是不包括角色相关
     * 不包括手机
     */
    @ApiOperation(value = "修改用户")
    @PostMapping("/update")
    public Result updateUser(@RequestBody TotalEntity totalEntity) {

        try {
            UserEntity user = totalEntity;
            //加密
            user.setPassword(MD5.encrypt(user.getPassword()));
            userService.saveOrUpdate(user);

            Integer flag = userService.updateUser(totalEntity);
            System.out.println(flag);
            if (flag > 0) {
                return Result.ok();
            }
            return Result.error();
        } catch (Exception e) {
            //手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            throw new MyException(20001,"异常");
        }

    }

    @ApiOperation(value = "批量添加用户")
    @PostMapping("/addUserList")
    public Result batchAddUser(MultipartFile file) {
        //上传过来excel文件
        Boolean flag = userService.saveUserList(file, userService);
        if (flag) {
            return Result.ok().message("批量插入成功");
        }
        return Result.error().message("批量插入失败");

    }


    /**
     * 删除用户
     */
    @ApiOperation(value = "删除用户")
    @PostMapping("/delete/{userId}")
    public Result deleteUser(@PathVariable int userId) {

        //TODO 参数校验
        boolean flag = this.userService.deleteUser(userId);

        if (flag) {
            return Result.ok();
        }
        return Result.error();

    }

    /**
     * 查询运行结果
     */
    @ApiOperation(value = "查询运行结果")
    @PostMapping("/checksStatus")
    public Result checksStatus() {

        Boolean outValue = userService.getOutValue();

        if (StringUtils.isEmpty(outValue)) {
            return Result.ok().message("当前无任务");
        }

        if (outValue) {
            return Result.ok().data("运行结果", outValue);
        }

        return Result.error().message("任务运行中。。。。");


    }

    /**
     * 分页用户接口
     */
    @ApiOperation(value = "分页功能")
    @GetMapping("/page/{current}/{limit}")
    public Result pageUserList(
            @ApiParam(name = "current", value = "当前页", required = true)
            @PathVariable long current,
            @ApiParam(name = "limit", value = "每页展示个数", required = true)
            @PathVariable long limit) {

        //创建page对象
        Page<UserEntity> pageUser = new Page<>(current, limit);

        //调用方法实现分页
        //调用方法时候，底层封装，把分页所有数据封装到page对象里面
        userService.page(pageUser, null);

        //总记录数
        long total = pageUser.getTotal();
        //数据list集合
        List<UserEntity> records = pageUser.getRecords();

        return Result.ok().data("total", total).data("rows", records);
    }

}
